package com.gitee.melin.bee.core.jdbc.dialect.impl;

import com.gitee.melin.bee.core.jdbc.dialect.AbstractJdbcDialect;
import com.gitee.melin.bee.core.jdbc.enums.DataSourceType;
import com.gitee.melin.bee.core.jdbc.relational.BeeTableType;
import com.gitee.melin.bee.core.jdbc.relational.ConnectionInfo;
import java.sql.Connection;
import java.sql.Driver;
import java.sql.SQLException;
import org.apache.commons.lang3.StringUtils;

public class DaMengJdbcDialect extends AbstractJdbcDialect {

    @Override
    public DataSourceType getDataSourceType() {
        return DataSourceType.DAMENG;
    }

    public DaMengJdbcDialect(ConnectionInfo connectionInfo) {
        super(connectionInfo);
    }

    public DaMengJdbcDialect(Connection connection) {
        super(connection);
    }

    @Override
    protected Driver getDriver() throws SQLException {
        return loadDriver(DataSourceType.DAMENG.getDriverClass());
    }

    @Override
    protected boolean filterSchema(String schemaName) {
        if (schemaName.equalsIgnoreCase("sys")
                || schemaName.equalsIgnoreCase("sysauditor")
                || schemaName.equalsIgnoreCase("sysdba")
                || schemaName.equalsIgnoreCase("syssso")) {
            return false;
        }
        return super.filterSchema(schemaName);
    }

    @Override
    protected String getSelectTablesSql(String tableName) {
        String sql = "SELECT A.OWNER                    TABLE_SCHEMA,\n"
                + "       A.TABLE_NAME,\n"
                + "       A.NUM_ROWS                 TABLE_ROWS,\n"
                + "       A.AVG_ROW_LEN * A.NUM_ROWS DATA_SIZE,\n"
                + "       A.PARTITIONED              TABLE_PARTITION,\n"
                + "       B.COMMENTS                 TABLE_COMMENT,\n"
                + "       null                       CREATE_TIME,\n"
                + "       null                       UPDATE_TIME\n"
                + "FROM dba_tables A\n"
                + "         JOIN ALL_TAB_COMMENTS B ON\n"
                + "    A.OWNER = B.OWNER AND A.TABLE_NAME = B.TABLE_NAME\n"
                + "WHERE A.OWNER = :schemaName";
        if (StringUtils.isNotBlank(tableName)) {
            sql += " AND TABLE_NAME = :tableName";
        }
        return sql;
    }

    @Override
    protected String getSelectColumnsSql() {
        return "SELECT COLUMNS.COLUMN_NAME\n"
                + "     , COLUMNS.DATA_TYPE\n"
                + "     , COLUMNS.DATA_TYPE AS COLUMN_TYPE\n"
                + "     , COLUMNS.DATA_LENGTH\n"
                + "     , COLUMNS.NUMERIC_PRECISION\n"
                + "     , COLUMNS.NUMERIC_SCALE\n"
                + "     , null AS DATETIME_PRECISION\n"
                + "     , COLUMNS.IS_NULLABLE\n"
                + "     , COLUMNS.DATA_DEFAULT AS DEFAULT_VALUE\n"
                + "     , COMMENTS.COMMENTS AS COLUMN_COMMENT\n"
                + "FROM ALL_TAB_COLUMNS COLUMNS\n"
                + "LEFT JOIN ALL_COL_COMMENTS COMMENTS\n"
                + "ON COLUMNS.OWNER = COMMENTS.SCHEMA_NAME\n"
                + "    AND COLUMNS.TABLE_NAME = COMMENTS.TABLE_NAME\n"
                + "    AND COLUMNS.COLUMN_NAME = COMMENTS.COLUMN_NAME\n"
                + "WHERE COLUMNS.OWNER = :schemaName\n"
                + "  AND COLUMNS.TABLE_NAME = :tableName\n"
                + "ORDER BY COLUMNS.COLUMN_ID ASC";
    }

    @Override
    protected String getDDLColumnName(BeeTableType type) {
        return "ct_script";
    }

    @Override
    protected String createTableSql(BeeTableType type, String schemaName, String tableName) {
        if (BeeTableType.TABLE == type) {
            return "SELECT DBMS_METADATA.GET_DDL('TABLE', '"
                    + schemaName
                    + "', '"
                    + tableName
                    + "') as ct_script FROM DUAL";
        } else if (BeeTableType.VIEW == type) {
            return "SELECT DBMS_METADATA.GET_DDL('VIEW', '"
                    + schemaName
                    + "', '"
                    + tableName
                    + "') as ct_script FROM DUAL";
        } else {
            return "SELECT DBMS_METADATA.GET_DDL('MATERIALIZED_VIEW', '"
                    + schemaName
                    + "', '"
                    + tableName
                    + "') as ct_script FROM DUAL";
        }
    }
}
